home *** CD-ROM | disk | FTP | other *** search
/ Apple II Magazines (DO) / Nibble Volume 12, No. 05 (1991-05)(MindCraft Publishing)(Side B).zip / Nibble Volume 12, No. 05 (1991-05)(MindCraft Publishing)(Side B).do / PROFINDER.S2.txt < prev    next >
Text File  |  1996-12-24  |  21KB  |  738 lines

  1. *********************************************
  2. *               PROFINDER.S2                *
  3. *       ProFinder source code, Part 2       *
  4. *********************************************
  5. * ---------------------------------
  6. *   FILE UTILITY COMMAND HANDLERS
  7. * ---------------------------------
  8. * <S> Create Subdir command
  9. M.CRDIR DCI 'Subdirectory name: '
  10. CREATEDIR LDA #$40 ;If current dir pathname is
  11.  CMP PN1L ;64 chars long, can't do this
  12.  BEQ ERRORJ1
  13.  PRINT M.CRDIR, ;Ask for subdir name
  14.  JSR INPUTPN ;Input it
  15.  BCS RTS1 ;Cancel command if <ESC> pressed
  16.  JSR CROUT2
  17.  MLI $C0,P.CRDIR, ;CREATE the subdirectory
  18.  BCS ERRORJ1 ;Error exit
  19.  BCC UPDIR ;Update current dir
  20. *
  21. * <K> Lock/Unlock command
  22. LKUNLK JSR GETINFO ;Get file info
  23.  BCS ERRORJ1
  24.  LDA INFOACC
  25.  EOR #%11000010 ;If Destroy, Rename, Write access bits
  26.  BIT ACCBITS ;are set then it is Unlocked,
  27.  BEQ LKUNLK1 ;so Lock it.
  28.  ORA #%11000010 ;Otherwise it is Locked, so Unlock it
  29. ACCBITS EQU *-1
  30. LKUNLK1 ORA #%00000001 ;(Always set Read access bit)
  31.  STA INFOACC
  32.  JSR SETINFO ;Update file info
  33.  BCC UPDIR ;Update current dir if successful
  34. ERRORJ1 JMP ERROR ;Error exit
  35. *
  36. * <R> Rename command (for files)
  37. RENAMEFIL JSR FINDSLASH
  38.  STX PN1L ;Clear last filename in PN1
  39.  PRINT M.RENAME, ;Ask for new name
  40.  JSR INPUTPN ;Input it
  41.  BCS RTS1 ;Cancel command if <ESC> pressed
  42.  JSR CROUT2
  43.  MLI $C2,P.RENAME,  ;RENAME (Old name in PN2, new in PN1)
  44.  BCS ERRORJ1 ;Error
  45.  BCC UPDIR ;Update dir
  46. *
  47. * <D> Delete command
  48. M.DELETE DCI 'Delete this file'
  49. DELETE PRINT M.DELETE, ;Ask if want to delete
  50.  JSR YN ;Get "Y" or "N"
  51.  BCS RTS1 ;If "N" then exit
  52.  MLI $C1,P.DESTROY,  ;DESTROY the file
  53.  BCS ERRORJ1
  54. *
  55. * UPDIR:  Update current directory by reading it again
  56. *         Necessary when files in dir modified (renamed, locked, etc.) 
  57. UPDIR LDX #<PND
  58.  JSR MOVPNX1 ;Fetch dir pathname
  59.  JSR READDIR ; & read it
  60.  BCS NEWDISK
  61. RTS1 RTS
  62. *
  63. * <ESC> New Disk command, also called at START
  64. NEWDISK LDX #0
  65.  STX DIRLEVEL ;DIRLEVEL=0: in Volume Commands Menu
  66.  STX MENUNUM
  67.  LDA DIRSTACK ;Fetch choice no. of last disk drive used
  68.  STA CHOICE ;Make it current choice
  69.  LDY DEVCNT
  70.  INY
  71.  STY ACTIVEENT ;Put # of disk drives into ACTIVEENT
  72. NDLOOP LDX MENUNUM ;For each disk drive,
  73.  CPX ACTIVEENT ;identify slot & drive number
  74.  BCS RTS1 ;and store in menu entry
  75.  INX
  76.  STX MENUNUM
  77.  JSR CLEARMENU ;Clear menu entry of former info
  78.  JSR GETUNITNO ;Get unit no. of disk drive
  79.  TAX
  80.  BMI ND1 ;unit no. negative means "drive 2"
  81.  LDA #'1'
  82.  BNE ND2
  83. ND1 LDA #'2'
  84. ND2 LDY #8 ;Store drive no. (1-2) in menu entry
  85.  STA (MENUPTR),Y ;at Htab 8
  86.  TXA
  87.  LSR A ;Now get slot no. (1-7) from unit no.
  88.  LSR A
  89.  LSR A
  90.  LSR A
  91.  AND #$07
  92.  ORA #'0' ;Convert slot no. to ASCII
  93.  LDY #3
  94.  STA (MENUPTR),Y ;Store slot no. at Htab 3
  95.  JMP NDLOOP ;Go to next drive
  96. *
  97. * <B> Back Directory command
  98. BACKDIR LDX DIRLEVEL ;If DIRLEVEL=1 then in root dir,
  99.  CPX #2 ;so treat as <ESC> New Disk command
  100.  BCC NEWDISK
  101.  JSR GETINFO ;Make sure current dir is online
  102.  BCS ERROR
  103.  DEC PN1L ;Truncate the last dir filename
  104.  JSR FINDSLASH ;from the whole pathname
  105.  STX PN1L
  106.  JSR READDIR ;Read parent directory
  107.  BCS ERROR
  108.  DEC DIRLEVEL ;If successful, get choice no. of the
  109.  LDX DIRLEVEL ;dir just left from the directory stack
  110.  LDA DIRSTACK,X ;so that the bar cursor will appear
  111.  STA CHOICE ;on the DIR file user just left.
  112. RTS2 RTS
  113. *
  114. * <P> Set Prefix command
  115. SETPFX JSR MOVPN12 ;Set prefix to current dir
  116.  MLI $C6,P.PREFIX,  ;SET_PREFIX
  117.  BCC RTS2
  118. *
  119. * ERROR:  Display error message and wait for keypress
  120. * Note:  WAITKEY, GETKEY, and UPCASE are called independently
  121. ERROR JSR PRERR ;Print error message
  122. WAITKEY PRINT M.WAITKEY, ;Ask for keypress
  123. GETKEY STA STROBE ;Clear keyboard
  124.  JSR RDKEY ;Get keypress
  125. UPCASE AND #$7F
  126.  CMP #'a' ;Convert to uppercase (with high bit off)
  127.  BCC UPCASE1
  128.  CMP #'z'+1
  129.  BCS UPCASE1
  130.  AND #$5F
  131. UPCASE1 RTS
  132. M.WAITKEY DCI 'Press any key.  '
  133. * ------------------
  134. *  <C> Copy command
  135. * ------------------
  136. COPY LDA #$82 ;Make sure active prefix exists,
  137.  LDY PFXPTR ;or else report "NO PREFIX" error
  138.  BEQ ERRORJ4
  139.  JSR GETINFO ;Get info of file to be copied
  140.  BCS ERRORJ4
  141.  LDA #$4B
  142.  DEX  ;Storage type must be 1, 2, or 3--Standard
  143.  CPX #3 ;or else "FILE TYPE MISMATCH"
  144.  BCS ERRORJ4
  145.  JSR OPENPN2 ;Open source file
  146.  BCS ERRORJ4
  147.  MLI $D1,P.EOF, ;GET_EOF call, remember EOF of source file
  148.  BCS ERRORC
  149.  LDX #$FF ;SPARSE FILE DETECTOR TEST:
  150.  CLC  ;Carry clear to subtract 1
  151. COPY1 INX
  152.  LDA #0 ;Zero ENDMARK to start reading at
  153.  STA ENDMARK,X ;beginning of file
  154.  LDA EOF,X
  155.  SBC #0 ;Subtract 1 from EOF of file; store result
  156.  STA MARK,X ;in MARK
  157.  TXA
  158.  EOR #2 ;EOR: Compare with 2 w/out changing Carry
  159.  BNE COPY1
  160.  BCC COPY2 ;If EOF=0 then seedling file
  161.  LSR MARK+2
  162.  ROR MARK+1 ;Calculate ((EOF - 1) / 512)
  163.  LDY MARK+2 ;Y = (# index blocks - 1)
  164.  BNE COPY3 ;If Y>0 then tree file
  165.  LDA MARK+1 ;A = (# data blocks - 1)
  166.  BEQ COPY2 ;If A=0 then seedling file
  167.  CLC
  168.  ADC #2 ;Sapling file: #blocks = (# data blks + 1)
  169.  TAX
  170.  BCC COPY4
  171.  INY
  172.  BCS COPY4
  173. COPY2 LDX #1 ;Seedling file: #blocks = 1
  174.  LDY #0
  175.  BEQ COPY4
  176. COPY3 TYA  ;Tree file: #blocks = (# data blks +
  177.  CLC  ;                      # index blks + 1)
  178.  ADC #3
  179.  ADC MARK+1
  180.  TAX
  181.  BCC COPY4
  182.  INY
  183. COPY4 LDA #$84 ;Make sure #blocks file ACTUALLY has
  184.  CPX INFOBLKS ;is same as #blocks file SHOULD have if
  185.  BNE ERRORC ;it were sequential.  If not, then FILE IS
  186.  CPY INFOBLKS+1 ;SPARSE and this program can't copy it.
  187.  BEQ COPY5
  188. ERRORC JSR CLOSEALL ;Close all before error exit
  189. ERRORJ4 JMP ERROR ;Error exit
  190. COPY5 JSR READHUNK ;OK to copy:  Read hunk of source file
  191.  BCS ERRORJ4
  192.  LDX #0
  193.  LDA INFOTYP ;Make target file type different from
  194.  BNE COPY6 ;source file type (temporarily) so they
  195.  LDX #2 ;can be distinguished in case they should
  196. COPY6 STX CRTYP ;have the same name.
  197.  LDX #3
  198. COPY7 LDA INFOCDAT,X ;Make target file have same created date
  199.  STA CRCDAT,X ;as source file
  200.  DEX
  201.  BPL COPY7
  202.  JSR FINDSLASH
  203.  LDY #0 ;Copy filename to beginning of
  204. COPY8 LDA PN1S,X ;PN1 with no slash in front of it,
  205.  STA PN1S,Y ;so prefix will be used to locate
  206.  INX  ;target file. 
  207.  INY  ;Default target filename will be same
  208.  CPX PN1L ;as source filename.
  209.  BCC COPY8
  210.  STY PN1L
  211. COPYA JSR HOME19
  212.  PRINT M.COPY, ;Ask user for target filename
  213.  JSR PRINT1
  214.  JSR INPUTPN ;Get target filename (in PN1)
  215.  BCC COPYA1
  216.  RTS  ;Exit if user presses <ESC>
  217. COPYA1 JSR CLCMD ;Clear command area at bottom of screen
  218.  LSR F.SWAP ;Start by assuming user not swapping disks
  219.  MLI $C0,P.CREATE,  ;CREATE the target file
  220.  BCC COPYLOOP
  221.  CMP #$47 ;If DUPLICATE FILE NAME error, print
  222.  BEQ COPYA2 ;message and let user try again.
  223.  BCS ERRORJ4 ;If any Path Not Found error, print
  224.  CMP #$44 ;PREFIX NOT FOUND and let user try again.
  225.  BCC ERRORJ4 ;Other errors: Don't try again.
  226.  LDA #$83
  227. COPYA2 JSR ERROR
  228.  JMP COPYA
  229. *
  230. COPYLOOP JSR OPENPN1 ;Open target file
  231.  BCS ABORT ;Abort copy if error
  232.  JSR WRITEHUNK ;Write to target file
  233.  BCS ABORT
  234.  BIT F.EOF ;If EOF in source file reached while 
  235.  BMI COPYEND ;reading it, then finished copying.
  236.  BIT F.SWAP
  237.  BPL COPYL2 ;If user not swapping disks, skip:
  238. COPYL1 PRINT M.INSRCE, ;Ask user to insert source disk
  239.  JSR INSERTD ;Wait for user to insert disk
  240. COPYL2 LDA #<PN2
  241.  JSR CHECKFILE ;Check for source file online
  242.  BVS ABORT ;Abort if critical error
  243.  BCS COPYL1 ;Ask user again if source file not online
  244.  LDA INFO2TYP ;Make sure we have source, not target
  245.  CMP INFOTYP ;file: filetypes should match.
  246.  BNE COPYL1
  247.  JSR OPENPN2 ;Open source file
  248.  BCS ABORT
  249.  JSR READHUNK ;Read another hunk from it
  250.  BCS ABORT
  251.  BIT F.SWAP
  252.  BPL COPYL4 ;If user not swapping disks, skip:
  253. COPYL3 PRINT M.INTARG, ;Ask user to insert target disk
  254.  JSR INSERTD ;Wait for user to insert disk
  255. COPYL4 LDA #<PN1
  256.  JSR CHECKFILE ;Check for target file online
  257.  BVS ABORT ;Abort if critical error
  258.  BCS COPYL3 ;Ask user again if target file not online
  259.  LDA INFO2TYP ;Make sure we have target, not source
  260.  CMP INFOTYP ;file: filetypes should differ
  261.  BEQ COPYL3
  262.  BNE COPYLOOP ;Repeat loop
  263. *
  264. COPYEND JSR SETINFO ;COPYEND: set file info of target file
  265.  BCC RTS4 ;to file info of source file and exit.
  266. ABORT JSR CLOSEALL ;ABORT: close all files,
  267.  PHA  ;save error code,
  268.  MLI $C1,P.DESTROY,  ;delete the incomplete target file,
  269.  PLA  ;restore error code, 
  270.  JMP ERROR ;and exit through ERROR routine.
  271. *
  272. * Check if source or target file is online (specify which with A-reg)
  273. CHECKFILE STA INFO2PN+1 ;Set up parm table 
  274.  LDA #$80 ;(Use P.INFO2 parm table to avoid
  275.  STA INFO2PN ; overwriting P.INFO parm table)
  276.  LDA #$A
  277.  STA P.INFO2
  278.  MLI $C4,P.INFO2, ;GET_FILE_INFO
  279.  BCS CHECKF2
  280. CHECKF1 CLV  ;No error: exit with C,V clear
  281.  RTS
  282. CHECKF2 CMP #$47 ;Path Not Found error ($44,$45,$46):
  283.  BCS CHECKF3 ;exit with C set but V clear
  284.  CMP #$44
  285.  BCS CHECKF1
  286. CHECKF3 BIT RTS4 ;Critical error (any error other than
  287. RTS4 RTS  ;Path Not Found):  exit with V set.
  288. *
  289. * INSERTD:  Wait for user to insert disk
  290. *   Note:  CLCMD, VTAB19, VTABLINE, HOME19 called independently
  291. INSERTD SEC  ;Assume user is swapping disks (because 
  292.  ROR F.SWAP ;user had to be asked to insert right
  293.  JSR WAITKEY ;disk at least once) and Wait for user.
  294. CLCMD JSR VTAB19 ;CLCMD: Clear cmd area at bottom of screen
  295.  LDX #165 ;except for "target filename:" info on
  296.  JSR PRBL2 ;bottom line; done by printing 165 spaces.
  297. VTAB19 LDA #19 ;VTAB19: Vtab to line 19 and Htab 0.
  298. VTABLINE LDY #0 ;VTABLINE: Vtab to A-reg and Htab 0.
  299.  STY CH
  300.  JMP TABV
  301. HOME19 JSR VTAB19 ;HOME19: Clear from line 19 to bottom;
  302.  JMP CLEOP ;this region used as command area.
  303. *
  304. M.COPY ASC 'Copying file to Prefix--'
  305.  DFB CR,CR
  306. M.INTARG ASC 'Insert target disk.'
  307.  DFB CR,CR+$80
  308.  DCI 'Enter target filename: '
  309. M.INSRCE ASC 'Insert source disk.'
  310.  DFB CR,CR+$80
  311. *
  312. * Read a hunk of the source file
  313. READHUNK LDA MEMLO ;All of the memory from MEMLO to MEMHI 
  314.  STA RWDATA ;is available for copying, so start
  315.  LDA MEMLO+1 ;reading at MEMLO and
  316.  STA RWDATA+1 ;read (MEMHI-MEMLO) bytes.
  317.  SEC
  318.  LDA MEMHI
  319.  SBC MEMLO
  320.  STA RWCOUNT
  321.  LDA MEMHI+1
  322.  SBC MEMLO+1
  323.  STA RWCOUNT+1
  324.  LDX #2
  325. RH1 LDA ENDMARK,X ;Start reading within file at ENDMARK
  326.  STA MARK,X ;where last read ended.  If this is first
  327.  STA STARTMARK,X ;time read, then ENDMARK should be zeroed.
  328.  DEX
  329.  BPL RH1
  330.  MLI $CE,P.MARK, ;SET_MARK
  331.  BCS CLOSEJ2
  332.  JSR READ ;Now read it
  333.  BCS CLOSEJ2
  334.  MLI $CF,P.MARK, ;GET_MARK to update MARK
  335.  BCS CLOSEJ2
  336.  SEC
  337.  ROR F.EOF
  338.  LDX #2
  339. RH2 LDA MARK,X ;Move new MARK to ENDMARK for next read.
  340.  STA ENDMARK,X
  341.  CMP EOF,X ;If MARK <> EOF, then clear F.EOF flag
  342.  BEQ RH3 ;to indicate not all of file has been read
  343.  LSR F.EOF ;yet.  Otherwise leave F.EOF flag set.
  344. RH3 DEX
  345.  BPL RH2
  346.  CLC
  347. CLOSEJ2 JMP CLOSEALL ;Exit via close.
  348. *
  349. * Write a hunk to target file
  350. WRITEHUNK LDA RWTRANS ;Write same # of bytes that was read
  351.  STA RWCOUNT ;during last READHUNK call.
  352.  LDA RWTRANS+1
  353.  STA RWCOUNT+1
  354.  LDX #2
  355. WH1 LDA STARTMARK,X ;Start writing within file at
  356.  STA MARK,X ;STARTMARK, where last read started.
  357.  DEX
  358.  BPL WH1
  359.  MLI $CE,P.MARK, ;SET_MARK
  360.  BCS CLOSEJ1
  361.  MLI $CB,P.RW, ;WRITE
  362.  BCS CLOSEJ1
  363.  MLI $CC,P.CLOSE, ;CLOSE file specifically to detect errors
  364. CLOSEJ1 JMP CLOSEALL ;then exit via CLOSEALL.
  365. * -------------------
  366. *   READ DIRECTORY     Input: directory pathname in PN1
  367. * -------------------  Output: file catalog info in menu entries
  368. READDIR JSR FINDSLASH
  369.  CPX PN1L ;If directory pathname doesn't
  370.  BEQ RD1 ;already end in a "/", then
  371.  LDX PN1L ;put a "/" at the end of it.
  372.  LDA #'/'
  373.  STA PN1S,X
  374.  INC PN1L
  375. RD1 JSR OPENPN1 ;Open dir file
  376.  BCS RTS3
  377.  LDA #0
  378.  STA RWDATA ;Read entire directory file all at once
  379.  STA RWCOUNT ;beginning at DIRLOAD
  380.  LDA #<DIRLOAD ;up to MAXDIRSIZ bytes.
  381.  STA RWDATA+1 ;(MAXDIRSIZ sufficient to read very
  382.  LDA #<MAXDIRSIZ ; large directories)
  383.  STA RWCOUNT+1
  384.  JSR READ ;Read it
  385.  JSR CLOSEALL
  386.  BCS RTS3 ;Error exit
  387.  LDX #<PND
  388.  JSR MOVPN1X ;Move dir pathname to PND
  389.  LDX #0
  390.  STX ACTIVEENT ;Initialize ACTIVEENT to 0
  391.  LSR RWTRANS+1 ;(RWTRANS / 512) = # blocks of dir read
  392.  LDA FILECOUNT+1
  393.  BEQ RD2 ;If more than 255 files in dir,
  394.  LDA #$FF ;truncate at 255 (that's all MENU routine
  395.  STA FILECOUNT ;can handle anyway).
  396. RD2 JSR GETBLOCK ;Set Entry Pointer (ENTPTR) to first
  397.  BMI RDEND ;dir block.
  398.  JSR NEXTENT ;Skip dir header.
  399. RDLOOP LDX ACTIVEENT
  400.  CPX FILECOUNT ;If file count reached, end
  401.  BEQ RDEND
  402.  LDY #0
  403.  LDA (ENTPTR),Y ;Get length of filename of an entry
  404.  AND #$0F
  405.  BEQ RD3 ;Length = 0: inactive entry, skip it
  406.  INX
  407.  STX ACTIVEENT ;Add 1 to count of active entries
  408.  STA T.NAMELEN,X ;Save filename length in table
  409.  JSR CATENTRY ;Create catalog info for menu display
  410. RD3 LDA BLKENT
  411.  CMP ENTPERBLK ;End of one dir block?
  412.  BCS RD4
  413.  JSR NEXTENT ;No, go to next entry in same block
  414.  JMP RDLOOP
  415. RD4 JSR GETBLOCK ;Yes, go to next block
  416.  BPL RDLOOP ;Continue unless out of blocks.
  417. RDEND LDX ACTIVEENT ;End of dir read:
  418.  JSR SETPTR ;Set MEMHI to last entry (stored lowest in
  419.  STA MEMHI ;memory) so COPY command won't overwrite
  420.  STY MEMHI+1 ;menu entries.
  421.  CLC  ;Carry clear indicates no error
  422. RTS3 RTS
  423. *
  424. SETPTR INX  ;SETPTR: Sets up MENUPTR to a menu entry.
  425.  LDA #0 ; Call with X-reg = menu entry number
  426.  LDY #$BF
  427.  BNE SETPTR2 ;Menu entries start at $BF00 and go down
  428. SETPTR1 SEC
  429.  SBC #39 ;Each entry takes up 39 bytes
  430.  BCS SETPTR2
  431.  DEY
  432. SETPTR2 DEX  ;Formula:
  433.  BNE SETPTR1 ; MENUPTR = $BF00 - (39 * Entry no.)
  434.  STA MENUPTR
  435.  STY MENUPTR+1
  436.  RTS
  437. *
  438. GETBLOCK DEC RWTRANS+1 ;Get next block in dir 
  439.  BMI GETBLOCK1 ;(RWTRANS+1 counts #blocks left)
  440.  LDA #4
  441.  STA ENTPTR ;Point to first entry in block at byte #4
  442.  LDX RWDATA+1 ;(RWDATA+1 points to where block stored)
  443.  STX ENTPTR+1
  444.  INX  ;Increment RWDATA+1 pointer by $200 bytes
  445.  INX  ;to point to the next block in memory
  446.  STX RWDATA+1
  447.  LDA #1 ;Ready for first entry in block
  448.  STA BLKENT ;Exit with N-flag clear if got a block
  449. GETBLOCK1 RTS  ;Exit with N-flag set if no blocks left
  450. *
  451. NEXTENT INC BLKENT ;Go to next entry within same block
  452.  LDA ENTLEN
  453.  CLC  ;Increment entry pointer by entry length
  454.  ADC ENTPTR ;parameter given in dir header.
  455.  STA ENTPTR
  456.  BCC NEXTENT1
  457.  INC ENTPTR+1 ;Ready for next entry in block
  458. NEXTENT1 RTS
  459. *
  460. CATENTRY PHA  ;Create catalog info for a menu entry
  461.  JSR CLEARMENU ;(Call with filename length in A-reg,
  462.  PLA  ; ENTPTR set up, and menu entry no. in
  463.  TAY  ; X-reg.)
  464. CAT1 LDA (ENTPTR),Y ;Move filename from directory block entry
  465.  STA (MENUPTR),Y ;to menu entry.
  466.  DEY    
  467.  BNE CAT1
  468.  LDY #$1E
  469.  LDA (ENTPTR),Y ;Get access code from dir block entry
  470.  AND #%11000010
  471.  CMP #%11000010 ;If any of Write, Rename, Destroy access
  472.  BEQ CAT2 ;bits not set, then file is Locked
  473.  LDA #'*' ;so store an asterisk in front of filename
  474.  LDY #0 ;in menu entry
  475.  STA (MENUPTR),Y
  476. CAT2 LDY #$10
  477.  LDA (ENTPTR),Y ;Get file type code
  478.  LDY #18 ;(Put file type at Htab 18 on screen)
  479.  LDX #NFITYPES-1
  480. CAT3 CMP FITYPES,X ;Compare file type with list of
  481.  BEQ CAT4 ;known file types
  482.  DEX
  483.  BPL CAT3
  484.  TAX
  485.  LDA #'$' ;If unknown file type, then 
  486.  STA (MENUPTR),Y ;file type code is "$xx"
  487.  TXA
  488.  LSR A
  489.  LSR A
  490.  LSR A
  491.  LSR A
  492.  JSR STORENIB ;Store file type code in hex
  493.  TXA
  494.  JSR STORENIB
  495.  JMP CAT5
  496. CAT4 LDA FITYPES1,X ;If known file type, store its
  497.  STA (MENUPTR),Y ;three-letter abbreviation in menu entry
  498.  INY
  499.  LDA FITYPES2,X
  500.  STA (MENUPTR),Y
  501.  INY
  502.  LDA FITYPES3,X
  503.  STA (MENUPTR),Y
  504. CAT5 LDY #$21 ;Get modified date
  505.  LDA (ENTPTR),Y
  506.  BEQ CAT7 ;If no date, skip
  507.  PHA
  508.  AND #$1F ;Isolate day of month
  509.  TAX
  510.  INY
  511.  LDA (ENTPTR),Y ;Save second byte of mod. date
  512.  STA TEMP
  513.  JSR DEC1B ;Convert day to decimal
  514.  LDY #30
  515.  LDX #3
  516.  JSR PUTNUMX ;Store day (Htab 30) in menu entry
  517.  PLA
  518.  LSR TEMP
  519.  ROR A ;Isolate month
  520.  LSR A
  521.  LSR A
  522.  LSR A
  523.  LSR A
  524.  TAX
  525.  DEX
  526.  LDA #'-' ;Store "-"s between Day-Month-Year
  527.  LDY #36
  528.  STA (MENUPTR),Y
  529.  LDY #32
  530.  STA (MENUPTR),Y
  531.  INY
  532.  CPX #12
  533.  BCS CAT6
  534.  LDA MONTHS1,X ;Store month abbreviation
  535.  STA (MENUPTR),Y
  536.  INY
  537.  LDA MONTHS2,X
  538.  STA (MENUPTR),Y
  539.  INY
  540.  LDA MONTHS3,X
  541.  STA (MENUPTR),Y
  542. CAT6 LDA TEMP ;Isolate year
  543.  CLC
  544.  ADC #100 ;Add 100 for leading zero
  545.  TAX
  546.  JSR DEC1B ;Convert to decimal
  547.  LDY #37
  548.  LDX #3
  549.  JSR PUTNUMX ;Store year (Htab 37)
  550. CAT7 LDY #$13
  551.  LDA (ENTPTR),Y ;Get # blocks used
  552.  TAX 
  553.  INY
  554.  LDA (ENTPTR),Y
  555.  JSR DEC ;Convert to decimal
  556.  LDY #23 ;Store #blocks used at Htab 23
  557. PUTNUM LDX #0 ;PUTNUM:  called independently, it
  558. PUTNUMX LDA NUMBER,X ; moves decimal number from NUMBER to
  559.  STA (MENUPTR),Y ; menu entry at Htab (Y-reg).
  560.  INY
  561.  INX
  562.  CPX #5
  563.  BNE PUTNUMX
  564.  RTS
  565. *
  566. FITYPES DFB 1,4,6,8,$F,$19,$1A,$1B     ;Standard & AplWks file types
  567.  DFB $B0,$B1,$B2,$B3,$B4,$B5,$B6,$B7    ;ProDOS 16 file types
  568.  DFB $B8,$B9,$BA,$BB,$BF,$C0,$C1,$C8,$E2     ;More P16 types 
  569.  DFB $EF,$F0,$F9,$FA,$FB,$FC,$FD,$FE,$FF     ;ProDOS 8 types
  570.  DFB $A0,$A1,$A2,$A3,$A4        ;WordPerfect file types
  571. NFITYPES EQU *-FITYPES
  572. FITYPES1 ASC 'BTBFDAAASOLSRESTNCTDDPPFDPCPIIBVRSWMHDV'  ;File type
  573. FITYPES2 ASC 'AXIOIDWSRBI1TXTSDDORONIOTAM1NVAAEYPALAR'  ;codes.  Read
  574. FITYPES3 ASC 'DTNTRBPPCJB6LERFAALVCTCNSSD6TRSRLS CPTT'  ;vertically.
  575. MONTHS1 ASC 'JFMAMJJASOND'  ;Month names.
  576. MONTHS2 ASC 'AEAPAUUUECOE'  ;Read them vertically.
  577. MONTHS3 ASC 'NBRRYNLGPTVC'
  578. *
  579. DEC1B LDA #0 ;DEC1B: Convert 1-byte no. in X to decimal
  580. DEC STX VAL ;DEC: Convert 2-byte number to decimal
  581.  STA VAL+1 ; Call with value in (X low, A high)
  582.  LDX #0 ; Result stored (Ascii form) in NUMBER
  583.  LDA #SPACE
  584. DEC1 STA NUMBER,X ;Fill NUMBER string with spaces first
  585.  INX
  586.  CPX #5
  587.  BNE DEC1
  588. DEC2 DEX  ;Digit counter in X-reg
  589.  LDA #0 ;(X=4: on ones digit;  X=0: 10000's dig)
  590.  STA AUX
  591.  LDY #16 ;For 16-bit number, rotate it 16 times
  592. DEC3 ASL VAL
  593.  ROL VAL+1 ;Rotate the value left 1 bit at a time
  594.  ROL AUX ;and accumulate what comes out left side
  595.  LDA AUX ;in AUX.  Whenever 10 or more comes out
  596.  SEC  ;the left side into AUX, push 1 back into
  597.  SBC #10 ;the right side of VAL and subtract 10
  598.  BCC DEC4 ;from AUX, so that we divide by 10 while
  599.  INC VAL ;rotating.
  600.  STA AUX
  601. DEC4 DEY
  602.  BNE DEC3
  603.  LDA AUX ;What's left in AUX after 16 rotations
  604.  ORA #'0' ;is remainder after dividing VAL by ten.
  605.  STA NUMBER,X ;Convert it to ASCII digit & store it
  606.  LDA VAL ;in NUMBER.
  607.  ORA VAL+1 ;If VAL not zero then go
  608.  BNE DEC2 ;to the next higher digit (decimal place).
  609.  RTS  ;Otherwise done.
  610. *
  611. STORENIB AND #$0F ;Convert nibble in lower 4 bits of A-reg
  612.  CMP #$0A ;to a hex digit and store it in menu entry
  613.  BCC STORENIB1
  614.  ADC #6
  615. STORENIB1 ADC #'0'
  616.  INY
  617.  STA (MENUPTR),Y
  618.  RTS
  619. *
  620. CLEARMENU JSR SETPTR ;Find menu entry and fill all 39
  621.  LDY #38 ;bytes of it with spaces to
  622.  LDA #SPACE ;erase old info.  Call with menu entry
  623. CLEAR1 STA (MENUPTR),Y ;no. in X-reg.
  624.  DEY
  625.  BPL CLEAR1
  626.  RTS
  627. * INPUTPN:  Input filename from user.  Call with complete pathname
  628. *           in PN1; user will be allowed to modify last filename.
  629. *   Output: Carry clear = user pressed <RETURN>;  Carry set = <ESC>
  630. INPUTPN JSR FINDSLASH ;Isolate last filename in the pathname
  631.  STX STARTPOS ;STARTPOS = position within pathname
  632.  TXA  ; where last filename starts
  633.  CLC
  634.  ADC #$F ;Allow for 15-char filename
  635.  CMP #$40 ;OR 64-char pathname, whichever smaller
  636.  BCC INPUT1
  637.  LDA #$40
  638. INPUT1 STA ENDPOS ;ENDPOS = Max length user can enter
  639.  LDA CH
  640.  STA TEMP ;Save screen cursor position
  641.  JSR PRPN1X ;Print the default filename
  642.  LDA TEMP
  643.  STA CH ;Recall screen cursor position to start
  644.  LDX STARTPOS
  645. INLOOP JSR GETKEY ;Get keypress
  646.  CMP #CR ;If <RETURN> pressed, exit w/Carry clear
  647.  BNE IN1 ;However, <RETURN> not acceptable if
  648.  LDA STARTPOS ;no filename entered & no default
  649.  CMP PN1L ;filename used.
  650.  BEQ INLOOP
  651.  CLC
  652.  RTS
  653. IN1 CPX STARTPOS ;If cursor pos is at 1st char of filename,
  654.  BNE IN2 ;then only accept <A-Z> input,
  655.  CMP #ESC ;or <ESC> to cancel (return w/Carry set).
  656.  BNE INCHAR1
  657.  SEC
  658.  RTS
  659. IN2 CMP #ESC ;If cursor beyond 1st char of filename,
  660.  BNE IN3 ;then <ESC> starts input over again.
  661.  LDA TEMP
  662.  STA CH
  663.  LDX STARTPOS
  664.  JMP PUTCHAR2
  665. IN3 CMP #DEL ;Check for Delete key.
  666.  BNE IN4
  667.  LDA #LARROW ;Delete key treated as Left Arrow.
  668. IN4 CMP #LARROW ;Check for Left Arrow.
  669.  BNE INCHAR
  670.  DEX  ;If Left Arrow, go back 1 char.
  671.  JMP PUTCHAR1
  672. INCHAR CMP #'.' ;Acceptable characters are
  673.  BEQ PUTCHAR ;periods, letters, and digits.
  674.  CMP #'0'
  675.  BCC INLOOP
  676.  CMP #'9'+1
  677.  BCC PUTCHAR
  678. INCHAR1 CMP #'A'
  679.  BCC INLOOP
  680.  CMP #'Z'+1
  681.  BCS INLOOP
  682. PUTCHAR CPX ENDPOS ;If at end position (max length that can
  683.  BEQ INLOOP ;be allowed) then don't accept any more.
  684.  STA PN1S,X ;Store ASCII character in PN1.
  685.  INX  ;Increment cursor position.
  686. PUTCHAR1 ORA #$80
  687.  JSR COUT ;Print to screen.
  688. PUTCHAR2 STX PN1L ;Truncate everything after cursor: set
  689.  JSR CLEOL ; new PN1 length & clear rest of line.
  690.  JMP INLOOP ;Get another char.
  691. *
  692. PRPN1 LDX #0 ;Print Pathname 1:
  693. PRPN1X CPX PN1L ;Call PRPN1 to print all of PN1
  694.  BCS RTS5 ;Call PRPN1X to print portion of PN1
  695.  LDA PN1S,X ; following X-reg.
  696.  ORA #$80
  697.  JSR COUT
  698.  INX
  699.  JMP PRPN1X
  700. *
  701. * Ask user a Yes/No question.
  702. *  Output:  Carry clear if user responds "Y"; set if "N" or <ESC>
  703. YN PRINT M.YN
  704. YN1 JSR GETKEY ;Get keypress
  705.  CMP #ESC ;If <ESC>, exit with carry set.
  706.  BEQ RTS5
  707.  CMP #'Y'
  708.  BEQ YN2
  709.  CMP #'N' ;If "N", exit with carry set.
  710.  BNE YN1
  711. RTS5 RTS
  712. YN2 ORA #$80 ;If "Y",
  713.  JSR COUT ;print the "Y",
  714.  JSR CROUT2 ;print 2 CR's,
  715.  CLC  ;and return with carry clear.
  716.  RTS
  717. M.YN DCI '?  (Y/N):  '
  718. *
  719. * Find last slash "/" in PN1
  720. *  Output:  X = position of char after last slash
  721. FINDSLASH LDX PN1L ;Start searching at end and
  722. FINDSL1 DEX  ;move backwards.
  723.  BMI FINDSL2 ;If no "/"s found then return X = 0
  724.  LDA PN1S,X
  725.  EOR #'/' ;Test for "/" (high bit immaterial)
  726.  ASL A
  727.  BNE FINDSL1
  728. FINDSL2 INX  ;Found it.
  729.  RTS
  730. *
  731. CHKPOINT2 DFB $EF ;Checkpoint 2 must contain $EF
  732. *
  733. * NOTE:  PROGRAM COUNTER MAY NOT EXCEED $1F00 AT THIS POINT
  734. *
  735.  DS $1F00-*,0 ;FILL WITH ZEROS UP TO $1F00.
  736. * Finished.
  737.